import time
import wx
import vtk
import math
import numpy
import vtktudoss

try:
    import extended.BaseCalc as BaseCalc
except ImportError:
    import BaseCalc


def create(parent):    
    return Filters(parent)
    
class Filters:
        
    def __init__(self, parent):
        print "Filters module loaded."        
        self.parent = parent
        self.baseCalc = BaseCalc.create(self, self)     
        self.initiateFilterTimer = True
        self.initiateFilterReferencesTimer = True
        self.filtercounter = 0        
        self.filterreferencescounter = 0
        self.sessionvisible_A = True
        self.sessionvisible_B = True
        self.widgetFiltersOn = True
        self.inversekinematicsOn = False
        self.sequenceFilterOn = False
        self.visibleSplines = 0
        self.visibleReferences = 0
        
        #FILTERS
        self.jointAngleCollection = []
        min = None
        max = None
        filter_min = None
        filter_max = None
        
        Thorax1 = {'stanceID': 0, 'description' :  "Thorax\nflexion", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.spineWidget_elevation}
        Thorax2 = {'stanceID': 1, 'description' :  "Thorax\nlateral\nflexion", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.spineWidget_plane}
        Thorax3 = {'stanceID': 2, 'description' :  "Thorax\naxial\nrotation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.spineWidget_axial}
        AC1 = {'stanceID': 3, 'description' :  "Clavicle\nprotraction", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.clavicleWidget_elevation}
        AC2 = {'stanceID': 4, 'description' :  "Clavicle\nelevation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.clavicleWidget_plane}
        AC3 = {'stanceID': 5, 'description' :  "Clavicle\naxial\nrotation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.clavicleWidget_axial}
        SCAP1 = {'stanceID': 6, 'description' :  "Scapula\nprotraction", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.scapulaWidget_elevation}
        SCAP2 = {'stanceID': 7, 'description' :  "Scapula\nlateral\nrotation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.scapulaWidget_plane}
        SCAP3 = {'stanceID': 8, 'description' :  "Scapula\ntilt", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.scapulaWidget_axial}        
        GHabduction = {'stanceID': 9, 'description' :  "Humerus\nelevation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.GHWidget_elevation}
        GHplane = {'stanceID': 10, 'description' :  "Humerus\nelevation\nplane", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.GHWidget_plane}
        GHaxial = {'stanceID': 11, 'description' :  "Humerus\nexo-rotation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.GHWidget_axial}#
        ELflexion = {'stanceID': 12, 'description' :  "Elbow\nflexion", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.ELWidget_elevation}
        ELplane = {'stanceID': 13, 'description' :  "Elbow\nflexion\nplane", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.ELWidget_plane}
        ELaxial = {'stanceID': 14, 'description' :  "Elbow\npronation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.ELWidget_axial}
        
        HumThorax1 = {'stanceID': 15, 'description' :  "Humerus\nglobal\nelevation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.GHGlobal_elevation}
        HumThorax2 = {'stanceID': 16, 'description' :  "Humerus\nglobal\nelevation\nplane", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.GHGlobal_plane}
        HumThorax3 = {'stanceID': 17, 'description' :  "Humerus\nglobal\naxial\nrotation", 'min1': min, 'max1': max, 'min2': min, 'max2': max, 'filter_min': filter_min, 'filter_max': filter_max, 'widget': self.parent.gui.widgets.GHGlobal_axial}
        
        self.jointAngleCollection.append(Thorax1)
        self.jointAngleCollection.append(Thorax2)
        self.jointAngleCollection.append(Thorax3)
        self.jointAngleCollection.append(AC1)
        self.jointAngleCollection.append(AC2)
        self.jointAngleCollection.append(AC3)
        self.jointAngleCollection.append(SCAP1)
        self.jointAngleCollection.append(SCAP2)
        self.jointAngleCollection.append(SCAP3)
        self.jointAngleCollection.append(GHabduction)
        self.jointAngleCollection.append(GHplane)
        self.jointAngleCollection.append(GHaxial)
        self.jointAngleCollection.append(ELflexion)
        self.jointAngleCollection.append(ELplane)
        self.jointAngleCollection.append(ELaxial)
        self.jointAngleCollection.append(HumThorax1)
        self.jointAngleCollection.append(HumThorax2)
        self.jointAngleCollection.append(HumThorax3)

        self.plottedAngles = []
        self.filteredAngles = []

    def FilterSingleSpline_WithoutVisualisation(self, spline, isReferenceSpline, splineNr):
        # Not filtered until one of the filters returns False.
        valid = True
        
        if valid:
            # Second filter: check all the widgets for their filter ranges.
            if self.widgetFiltersOn:
                stance = spline['stance']
                for j in range(0,len(self.filteredAngles)):
                    #if any of the angles are outside of their respective filter ranges, break and return False.
                    #~ print self.jointAngleCollection[self.filteredAngles[j]]['filter_min'], ' - ',  self.jointAngleCollection[self.filteredAngles[j]]['filter_max']
                    if stance[self.filteredAngles[j]] < self.jointAngleCollection[self.filteredAngles[j]]['filter_min'] or \
                        stance[self.filteredAngles[j]] > self.jointAngleCollection[self.filteredAngles[j]]['filter_max']:
                        valid = False
                        break
            
        if valid:
            #Third filter: Inverse Kinematics?
            if self.inversekinematicsOn:
                if isReferenceSpline:
                    if splineNr in self.parent.IK.previoussplines2:
                        valid = True
                    else:
                        valid = False
                else:
                    if splineNr in self.parent.IK.previoussplines:
                        valid = True
                    else:
                        valid = False
              
        if valid:
            #sequence filter
            if self.sequenceFilterOn:
                for sequenceplotter in self.parent.gui.sequenceplotters:
                    if (isReferenceSpline and sequenceplotter.whichdata==1) or \
                        (not isReferenceSpline and sequenceplotter.whichdata==0):
                        for i in range(0, len(sequenceplotter.filtervalues)/2):
                            if splineNr >= sequenceplotter.filtervalues[i*2] and\
                                splineNr <= sequenceplotter.filtervalues[i*2 + 1]:
                                valid = False
                                break
                
        if valid:
            return True
        else:
            return False
            
            
                
    def FilterSingleSpline(self, spline, isReferenceSpline, splineNr):
        # Not filtered until one of the filters returns False.
        valid = True
        
        # First filter: dataset visible?
        if isReferenceSpline:
            if not self.sessionvisible_B:
                valid = False
        else:
            if not self.sessionvisible_A:
                valid = False
        
        if valid:
            # Second filter: check all the widgets for their filter ranges.
            if self.widgetFiltersOn:
                stance = spline['stance']
                for j in range(0,len(self.filteredAngles)):
                    #if any of the angles are outside of their respective filter ranges, break and return False.
                    #~ print self.jointAngleCollection[self.filteredAngles[j]]['filter_min'], ' - ',  self.jointAngleCollection[self.filteredAngles[j]]['filter_max']
                    if stance[self.filteredAngles[j]] < self.jointAngleCollection[self.filteredAngles[j]]['filter_min'] or \
                        stance[self.filteredAngles[j]] > self.jointAngleCollection[self.filteredAngles[j]]['filter_max']:
                        valid = False
                        break
            
        if valid:
            #Third filter: Inverse Kinematics?
            if self.inversekinematicsOn:
                if isReferenceSpline:
                    if splineNr in self.parent.IK.previoussplines2:
                        valid = True
                    else:
                        valid = False
                else:
                    if splineNr in self.parent.IK.previoussplines:
                        valid = True
                    else:
                        valid = False
              
        if valid:
            #sequence filter
            if self.sequenceFilterOn:
                for sequenceplotter in self.parent.gui.sequenceplotters:
                    if (isReferenceSpline and sequenceplotter.whichdata==1) or \
                        (not isReferenceSpline and sequenceplotter.whichdata==0):
                        for i in range(0, len(sequenceplotter.filtervalues)/2):
                            if splineNr >= sequenceplotter.filtervalues[i*2] and\
                                splineNr <= sequenceplotter.filtervalues[i*2 + 1]:
                                valid = False
                                break
                
        if valid:
            self.ShowSpline(spline, splineNr)
            return True
        else:
            self.HideSpline(spline, splineNr)
            return False
                

    def ShowSpline(self, spline, splineNr=None):   
        if spline['visible'] == False:
            if spline['reference']:
                self.visibleReferences = self.visibleReferences + 1
            else:
                self.visibleSplines = self.visibleSplines + 1
            
            self.parent.gui.ren3.AddActor(spline['splineActor'])
            try:
                self.parent.cellpicker.DeletePickList(spline['splineActor'])
            except AttributeError:
                pass
            self.parent.cellpicker.AddPickList(spline['splineActor'])  
            
            if self.parent.gui.posesOn == True:
                self.parent.gui.ren2.AddActor(spline['poseActor'])
                self.parent.gui.ren2.AddActor(spline['shadedArm'])            
            
            for scatterplot in self.parent.gui.scatterplotlist:
                if spline['reference']:
                    scatterplot.xyValues2.append([spline['stance'][scatterplot.stanceID1],\
                                                                    spline['stance'][scatterplot.stanceID2]])
                else:
                    scatterplot.xyValues1.append([spline['stance'][scatterplot.stanceID1],\
                                                                    spline['stance'][scatterplot.stanceID2]])
                
            spline['visible'] = True
        
    def HideSpline(self, spline, splineNr=None):
        if spline['visible'] == True:
            if spline['reference']:
                self.visibleReferences = self.visibleReferences - 1
            else:
                self.visibleSplines = self.visibleSplines - 1
            
            try:
                self.parent.cellpicker.DeletePickList(spline['splineActor'])
            except AttributeError:
                pass
            self.parent.gui.ren3.RemoveActor(spline['splineActor'])
            
            self.parent.gui.ren2.RemoveActor(spline['poseActor'])
            self.parent.gui.ren2.RemoveActor(spline['shadedArm'])
            spline['visible'] = False
            
            for scatterplot in self.parent.gui.scatterplotlist:
                try:
                    if spline['reference']:
                        scatterplot.xyValues2.remove([spline['stance'][scatterplot.stanceID1],\
                                                                    spline['stance'][scatterplot.stanceID2]])
                    else:
                        scatterplot.xyValues1.remove([spline['stance'][scatterplot.stanceID1],\
                                                                    spline['stance'][scatterplot.stanceID2]])
                except ValueError:
                    pass
                    
        #~ print self.removeditems
        #~ print "New number of pick items: ", self.parent.cellpicker.GetPickList().GetNumberOfItems()
        
    def RestartFiltering(self):
        self.filterEnd = self.filtercounter -1
        if self.filterEnd < 0:
            self.filterEnd = len(self.parent.splineCollection)
        self.initiateFilterTimer = False
        #~ print "Number of pick items: ", self.parent.cellpicker.GetPickList().GetNumberOfItems()
        self.removeditems = 0
                
    def RestartFilteringReferences(self):
        self.filterReferencesEnd = self.filterreferencescounter -1
        if self.filterReferencesEnd < 0:
            self.filterReferencesEnd = len(self.parent.splineReferences)
        self.initiateFilterReferencesTimer = False
        
    def FilterAllStepper(self):
        i = 0
        if self.filtercounter == self.filterEnd:
            self.initiateFilterTimer = True        
        while self.filtercounter != self.filterEnd and i < 200:
            self.FilterSingleSpline(self.parent.splineCollection[self.filtercounter], False, self.filtercounter)
                #~ self.parent.splineCollection[self.filtercounter]['visible'] = True
            #~ else:
                #~ self.parent.splineCollection[self.filtercounter]['visible'] = False
            
            self.filtercounter = self.filtercounter + 1
            if self.filtercounter >= len(self.parent.splineCollection):
                if self.filtercounter == self.filterEnd:
                    self.filtercounter = 0
                    self.initiateFilterTimer = True
                    break
                else:
                    self.filtercounter = 0
            i = i+1
        #self.parent.MedianMeanSpline()
        self.UpdateShaderOpacity()
        

    def FilterAllReferenceStepper(self):
        i = 0
        if self.filterreferencescounter == self.filterReferencesEnd:
            self.initiateFilterReferencesTimer = True
        while self.filterreferencescounter != self.filterReferencesEnd and i < 200:
            self.FilterSingleSpline(self.parent.splineReferences[self.filterreferencescounter], True, self.filterreferencescounter)
                #~ self.parent.splineReferences[self.filterreferencescounter]['visible'] = True
            #~ else:
                #~ self.parent.splineReferences[self.filterreferencescounter]['visible'] = False
            self.filterreferencescounter = self.filterreferencescounter + 1
            if self.filterreferencescounter >= len(self.parent.splineReferences):
                if self.filterreferencescounter == self.filterReferencesEnd:
                    self.filterreferencescounter = 0
                    self.initiateFilterReferencesTimer = True
                    break
                else:
                    self.filterreferencescounter = 0
            i = i+1
        self.UpdateShaderOpacity()

    def UpdateShaderOpacity(self):
        #bluealphamultiplier = 1.0-(min(0.5, self.visibleSplines/2000.0)) #1000 splines = 0.0, 60 splines = 0.0, 1 spline = 1.0
        bluealphamultiplier = max(1.0, 5.0 -  self.visibleSplines/40.0) + (float(self.parent.gui.editorpanel.slider_1.GetValue())/2.0)
        yellowalphamultiplier = max(1.0, 5.0 -  self.visibleReferences/40.0) + (float(self.parent.gui.editorpanel.slider_2.GetValue())/2.0)
        
        
        self.parent.blue_shader.AddShaderVariableFloat("alphamultiplier", bluealphamultiplier)
        self.parent.yellow_shader.AddShaderVariableFloat("alphamultiplier", yellowalphamultiplier)
        self.parent.exoblue_shader.AddShaderVariableFloat("alphamultiplier", bluealphamultiplier)
        self.parent.exoyellow_shader.AddShaderVariableFloat("alphamultiplier", yellowalphamultiplier)
        self.parent.bluespline_shader.AddShaderVariableFloat("alphamultiplier", bluealphamultiplier)
        self.parent.yellowspline_shader.AddShaderVariableFloat("alphamultiplier", yellowalphamultiplier)
           
                
                




class MyApp(wx.App):
    def OnInit(self):
        applic = Filters(None)
        return 1

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
    
    
    